通过 Vue.extend 封装JS组件
注:
以 Ant Design of Vue UI 库的 Modal 对话框二次封装为例子,配置成功后可直接 js 调用,也可按照原有 components 引入调用。
components 引入调用不做相关示例说明,Modal 对话框只是作为示例,可自定义组件,也可二次封装其他 UI 库组件。
先自定义相关组件
<!-- components/mModal/mModal.vue -->
<template>
<div>
<a-modal
:title="title"
:visible="visible"
:footer="null"
@cancel="cancel"
:width="`${width}px`"
>
<div :style="[contentStyle]" class="text-wrap m-modal-content-wrap">
<span>
<span>
<a-icon
:type="iconType"
v-if="icon"
theme="filled"
:style="[
{
color: '#F19423',
fontSize: '25px',
marginRight: '12px',
...iconStyle,
},
]"
class="m-modal-tips"
/>
</span>
<span v-html="content"></span>
</span>
</div>
<div class="m-modal-footer-wrap" v-if="footer">
<a-button v-if="cancelShow" @click="cancel">{{ cancelText }}</a-button>
<a-button type="primary" @click="ok">
{{ okText }}
</a-button>
</div>
</a-modal>
</div>
</template>
<script>
export default {
name: "mModal",
data() {
return {
title: "标题",
content: "",
visible: false,
cancelText: "取消",
okText: "确定",
cancelShow: false,
width: 600,
contentStyle: {},
footer: true,
iconType: "exclamation-circle",
icon: false,
iconStyle: {},
};
},
mounted() {},
methods: {
show(
obj = {
title: "测试",
content: "测试",
}
) {
// 组件的配置参数信息
for (let i in obj) {
if (this[i] != undefined) this[i] = obj[i];
}
this.$nextTick(() => {
this.visible = true;
});
},
hide() {
this.visible = false;
// 使用 setTimeout,减少移除的违和感
setTimeout(() => {
// 移除 DOM,释放内存
this.$destroy(true);
this.$el.parentNode.removeChild(this.$el);
}, 500);
},
cancel() {
this.hide();
},
ok() {
this.hide();
},
},
};
</script>
<style lang="less" scoped>
::v-deep {
.ant-modal-title {
font-size: 20px;
font-weight: bold;
}
.ant-modal-body {
overflow: hidden;
}
}
.m-modal-content-wrap {
min-height: 100px;
.m-modal-tips {
position: relative;
vertical-align: text-top;
}
}
.m-modal-footer-wrap {
display: flex;
align-content: center;
justify-content: center;
padding-top: 24px;
margin-top: 24px;
position: relative;
&::after {
position: absolute;
left: 50%;
transform: translateX(-50%);
border-top: 1px solid #eeeeee;
width: calc(200%);
top: 0;
content: "";
}
::v-deep {
.ant-btn {
width: 200px;
height: 40px;
font-size: 16px;
}
.ant-btn + .ant-btn {
margin-left: 20px;
}
}
}
</style>
- 配置 Vue.extend 相关文件信息
// components/mModal/index.js
import modal from "./mModal.vue";
import Vue from "vue";
let obj = (
data = {
title: "",
content: "",
}
) => {
// 通过 Promise 实现 组件内部方法的(重定义) callback 回调
return new Promise((resolve, reject) => {
// 创建构造器
let mModal = Vue.extend(modal);
// 创建 newModal 实例
let newModal = new mModal();
// 挂载到一个元素上
let vm = newModal.$mount();
// 获取 newModal 内容
let el = vm.$el;
// 将创建的 newModal 添加到 body 尾部
document.body.appendChild(el);
// 调用组件内部 show 方法,并传入组件自定义参数
newModal.show(data);
newModal.ok = () => {
newModal.hide();
resolve();
};
newModal.cancel = () => {
newModal.hide();
reject();
};
});
};
export default obj;
- 组件引入
// main.js
import Vue from "vue";
import mModal from "@/components/mModal";
Vue.prototype.$mModal = mModal;
- 组件调用。
// 具体配置参数根据自己组件内的 data 相关定义传参
this.$mModal({
title: "提示",
content: `具体内容`,
okText: "我知道了",
})
.then(() => {
// 点击了确定按钮
})
.catch(() => {
// 点击了取消按钮
});
Powered by Waline v2.15.8